
#include <boost/bind.hpp>
#include "CheckThread.h"
#include "../client-protocol/RequestSync.h"
#include "../client-common/VersionTag.h"
#include "../client-file/SyncFileModule.h"
#include "../client-protocol/BasicModule.h"
#include "../engine/DebugStream.h"

namespace Client {
namespace App {

using namespace Common;

#define DEFAULT_SERVER_ADDRESS "192.168.1.3"
//#define DEFAULT_SERVER_ADDRESS "61.148.212.59"
#define DEFAULT_SERVER_PORT 2555
#define CHECK_TIME_MSECS (5*60*1000)

CCheckThread::CCheckThread()
{
	CBasicModule::InitModule();
	Client::File::CSyncFileModule::InitModule();
}

void CCheckThread::Start()
{
	mThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CCheckThread::MessageLoop, this)));
	SendEmptyMessage(APP_ACTION_START);
}

void CCheckThread::MessageLoop()
{
	while(1) {

		try {
			boost::shared_ptr<CMessage> msg = mMsgQueue.pop(CHECK_TIME_MSECS);
			if(!msg) {
				if(mControlConnection) mControlConnection->Check(false);
			}
			else {
				switch(msg->mWhat) {
				case APP_ACTION_START :
					mControlConnection = boost::shared_ptr<CConnectionControl>(
									new CConnectionControl(string(DEFAULT_SERVER_ADDRESS), DEFAULT_SERVER_PORT, 2556)
									);
					mControlConnection->Start();
					mControlConnection->Check(true);
					SendEmptyMessage(APP_ACTION_SYNC_FILE);
					break;
				
				case APP_ACTION_EXIT:
					if(mControlConnection) mControlConnection->Close();
					return;

				case APP_ACTION_SYNC_FILE :
					DebugStream << "CCheckThread::MessageLoop() - sync file\n";
					VersionTagRef vt = CVersionTag::QueryLocalTag(string(VERSION_TAG_FILE));
					if(!vt) {
						DebugStream << "CCheckThread::MessageLoop() - no file tag\n";
						break;
					}

					TableRef t = CVersionTag::GetSerializedTable();
					if(t) {
						t->Add(vt);
						boost::shared_ptr<CRequestSync> r(new CRequestSync());
						r->SetContent(t->ToString(), string(PACKAGE_CONTENT_TYPE_JSON));
						mControlConnection->SendRequest(r);
					}
					break;
				}
			}
		}
		catch(std::exception& e) {
			Engine::DebugStream << "CCheckThread::MessageLoop() - " << e.what() << '\n';
		}
	}
}

void CCheckThread::SendEmptyMessage(int what)
{
	boost::shared_ptr<CMessage> msg(new CMessage(what));
	mMsgQueue.push(msg);
}

void CCheckThread::ApplyAuthCode(std::string& authcode)
{
	if(mControlConnection) mControlConnection->ApplyAuthCode(authcode);
}

} // Client
} // App